package com.cloudfast.manager.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import com.cloudfast.config.property.c.DefaultProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.cloudfast.channel.FTPChannel;
import com.cloudfast.manager.FileStorageManager;
import com.cloudfast.response.FileResponse;
import com.cloudfast.utils.FileUtils;

/**
 * ftp 文件操作类
 *
 * @author liuyw
 */
public class FtpStorageManagerImpl extends BaseManagerImpl implements FileStorageManager {

    private static final Logger logger = LoggerFactory.getLogger(Logger.class);

    private DefaultProperty defaultProperty;

    public FtpStorageManagerImpl(DefaultProperty storageConfig, int maxFileSize) {
        this.defaultProperty = storageConfig;
        this.maxFileSize = maxFileSize;
    }

    @Override
    public FileResponse upload(MultipartFile file) {
        return upload(file, null);
    }

    @Override
    public FileResponse upload(MultipartFile file, String prefix) {
        // 文件不能为空
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("文件不能为空");
        }

        // 不能超过最大支持
        if (file.getSize() > maxFileSize) {
            throw new RuntimeException("文件太大,已超出最大支持范围:" + maxFileSize);
        }
        // 获取文件名称
        String originalName = file.getOriginalFilename();
        // 获取后缀名称
        String suffix = FileUtils.getFilenameSuffix(originalName);
        // 获取需要保存的文件名称
        String radomName = FileUtils.getRadomName() + "." + suffix;

        // 获取文件保存的路径
        String storageFilePath = "/" + FileUtils.getYmdPath() + "/";
        if (StringUtils.isNotEmpty(prefix)) {
            storageFilePath = "/" + prefix + "/" + FileUtils.getYmdPath() + "/";
        }
        FileResponse fileResponse = null;
        try {
            fileResponse = upload(file.getInputStream(), storageFilePath, radomName);
            if (fileResponse != null) {
                fileResponse.setOriginalName(originalName);
                fileResponse.setFileSize(file.getSize());
                fileResponse.setBrowser(defaultProperty.getBrowserPrefix() + storageFilePath + radomName);
            }
        } catch (IOException e) {
            logger.error("", "读取文件流失败.");
        }

        return fileResponse;
    }

    @Override
    public FileResponse upload(InputStream stream, String filePath, String fileName) {
        FTPChannel ftpChannel = new FTPChannel();
        FTPClient ftpClient = ftpChannel.getChannel(defaultProperty, 60000);
        try {
            // 设置PassiveMode传输
            ftpClient.enterLocalPassiveMode();
            // 设置二进制传输，使用BINARY_FILE_TYPE，ASC容易造成文件损坏
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.setControlEncoding("UTF-8");
            this.changeFolder(ftpClient, filePath);
            // 上传文件
            String tempName = filePath + fileName;
            boolean flag = ftpClient
                    .storeFile(new String(tempName.replaceAll("//", "").getBytes("UTF-8"), "ISO-8859-1"), stream);
            if (flag) {
                return new FileResponse("", (filePath + "/" + fileName).replaceAll("//", "/"), fileName,
                        fileName.split("\\.")[1], 0, "");
            }
        } catch (Exception e) {
            logger.error("", e.getMessage());
        } finally {
            ftpChannel.closeFTP(ftpClient);
            try {
                stream.close();
            } catch (IOException e) {
                logger.error("关闭{}", e.getMessage());
            }
        }
        return null;
    }

    @Override
    public byte[] download(String filePath) {
        FTPChannel ftpChannel = new FTPChannel();
        FTPClient ftpClient = ftpChannel.getChannel(defaultProperty, 60000);
        String[] filePathName = filePath.split("/");
        String fileName = filePathName[filePathName.length - 1];
        this.changeFolder(ftpClient, filePath.replace(fileName, ""));
        ByteArrayOutputStream bout = null;
        byte[] data = null;
        InputStream is = null;
        try {
            File localFile = new File(localStoragePath(null), fileName);
            OutputStream writeFile = new FileOutputStream(localFile);
            ftpClient.retrieveFile(fileName, writeFile);
            writeFile.flush();
            writeFile.close();
            bout = new ByteArrayOutputStream();
            is = new FileInputStream(localFile);
            int len;
            byte[] bs = new byte[1024];
            while ((len = is.read(bs)) != -1) {
                bout.write(bs, 0, len);
            }
            // 转成byte字节
            data = bout.toByteArray();
            bout.flush();
            // 删除文件
            localFile.deleteOnExit();
        } catch (IOException e) {
            logger.error(e.getMessage());
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (bout != null) {
                    bout.close();
                }

            } catch (Exception e2) {
                logger.error(e2.getMessage());
            }

            ftpChannel.closeFTP(ftpClient);
        }
        return data;
    }

    @Override
    public int deleteFile(String filePath) {
        FTPChannel ftpChannel = new FTPChannel();
        FTPClient ftpClient = ftpChannel.getChannel(defaultProperty, 60000);
        int result = 0;
        try {
            if (StringUtils.isNotEmpty(filePath)) {
                String[] files = filePath.split(",");
                for (int i = 0; i < files.length; i++) {
                    String[] filePathName = files[i].split("/");
                    String fileName = filePathName[filePathName.length - 1];
                    this.changeFolder(ftpClient, filePath.replace(fileName, ""));
                    ftpClient.dele(fileName);
                    result = 1;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ftpChannel.closeFTP(ftpClient);
        }
        return result;
    }

    /**
     * 切换文件夹
     *
     * @param ftpClient
     * @param ftpPath
     */
    private void changeFolder(FTPClient ftpClient, String ftpPath) {
        String[] strPath = ftpPath.split("/");
        StringBuffer prevDir = new StringBuffer("");
        for (int i = 0; i < strPath.length; i++) {
            try {
                boolean successDir = ftpClient.changeWorkingDirectory(prevDir.toString() + "/" + strPath[i]);
                if (successDir) {
                    prevDir.append("/" + strPath[i]);
                } else {
                    ftpClient.makeDirectory(prevDir.toString() + "/" + strPath[i]);
                    ftpClient.changeWorkingDirectory(prevDir.toString() + "/" + strPath[i]);
                    prevDir.append("/" + strPath[i]);
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }

    @Override
    public List<File> iterationFile(String rootPath) {
        // TODO Auto-generated method stub
        return null;
    }

}
